package logic

import (
	"context"
	"fmt"
	"gitee.com/Cauchy_AQ/vxopen/model/mongodb"
	redis2 "gitee.com/Cauchy_AQ/vxopen/model/redis"
	"gitee.com/Cauchy_AQ/vxopen/utils"
	"github.com/tidwall/gjson"
	"time"

	"gitee.com/Cauchy_AQ/vxopen/rpc/wechat/internal/svc"
	"gitee.com/Cauchy_AQ/vxopen/rpc/wechat/wechat"

	"github.com/zeromicro/go-zero/core/logx"
)

type SubscribeLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

var (
	// API_VX_USERINFO 用户信息 url
	API_VX_USERINFO = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN"
)

func NewSubscribeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SubscribeLogic {
	return &SubscribeLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *SubscribeLogic) Subscribe(in *wechat.SubscribeReq) (*wechat.SubscribeResp, error) {
	// 1. 获取微信用户信息
	aToken, err := redis2.GetAvailableAToken(l.svcCtx.Config.ModelConfig)
	if err != nil {
		return nil, err
	}
	urls := fmt.Sprintf(API_VX_USERINFO, aToken, in.Openid)
	body, _ := utils.GetHttpsBody(urls)
	jsonStr := string(body)

	// 2. 用户信息插入数据库
	mongoClient := mongodb.GetMongoInstance(l.svcCtx.Config.ModelConfig)
	if err := mongoClient.UserCol.InsertByOpenId(context.Background(), &mongodb.User{
		OpenID: in.Openid,
		Name:   in.Openid,
		Role: mongodb.Role{
			Name:       "普通用户",
			Permission: []string{"home"},
		},
		SubscribeTime: gjson.Get(jsonStr, "subscribe_time").Int(),
	}); err != nil {
		return nil, err
	}

	// 3. 关注事件成功后，绑定 ticket 和 openid，用于前端的轮询查询登录状态
	l.svcCtx.RDB.Set(context.Background(), redis2.CacheQrcodeTicketPrefix+in.Ticket, in.Openid, ExpireQRCodeDefault*time.Second)

	// 4. 计入新用户
	key := redis2.CacheNewUsersPrefix + utils.GetMonth(time.Now())
	_, _ = l.svcCtx.RDB.Incr(context.Background(), key).Result()
	_, _ = l.svcCtx.RDB.Expire(context.Background(), key, redis2.CacheNewUsersPrefixTimeout).Result()

	return &wechat.SubscribeResp{
		MsgType:      "text",
		Content:      fmt.Sprintf("相识于<%s>\n ~~~~感谢关注！", time.Unix(gjson.Get(jsonStr, "subscribe_time").Int(), 0).Format("2006-01-02 15:04:05")),
		ToUserName:   in.Openid,
		FromUserName: in.ToUserName,
	}, nil
}
